package com.aw.baselib.util.download

import com.aw.baselib.util.AwLog
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadListener
import com.liulishuo.filedownloader.FileDownloadQueueSet
import com.liulishuo.filedownloader.FileDownloader

/**
 * Created by hzw.
 */
object AwFileDownloadUtil {
    private const val TAG = "FileDownloadUtil"
    private var totalCounts = 0
    private var finalCounts = 0
    fun startDownload(list: List<DownloadResBean>, serial: Boolean) {
        val queueSet = queueSet
        val tasks: MutableList<BaseDownloadTask> = ArrayList()
        for (temp in list) {
            val task = FileDownloader.getImpl().create(temp.url)
            task.path = temp.path
            tasks.add(task)
        }
        totalCounts += tasks.size
        AwLog.d(TAG, "startDownload totalCounts: " + totalCounts)
        if (serial) {
            // 串行执行该任务队列
            queueSet.downloadSequentially(tasks)
            // 如果你的任务不是一个List，可以考虑使用下面的方式，可读性更强
            //      queueSet.downloadSequentially(
            //              FileDownloader.getImpl().create(url).setPath(...),
            //              FileDownloader.getImpl().create(url).addHeader(...,...),
            //              FileDownloader.getImpl().create(url).setPath(...)
            //      );
        } else {
            // 并行执行该任务队列
            queueSet.downloadTogether(tasks)
            // 如果你的任务不是一个List，可以考虑使用下面的方式，可读性更强
            //    queueSet.downloadTogether(
            //            FileDownloader.getImpl().create(url).setPath(...),
            //            FileDownloader.getImpl().create(url).setPath(...),
            //            FileDownloader.getImpl().create(url).setSyncCallback(true)
            //    );
        }
        queueSet.start() // 最后你需要主动调用start方法来启动该Queue
    }

    private val queueSet: FileDownloadQueueSet
        private get() {
            val queueSet = FileDownloadQueueSet(queueTarget)
            //        queueSet.disableCallbackProgressTimes();// 由于是队列任务, 这里是我们假设了现在不需要每个任务都回调`FileDownloadListener#progress`, 我们只关系每个任务是否完成, 所以这里这样设置可以很有效的减少ipc.
            queueSet.setCallbackProgressMinInterval(1000)
            queueSet.setWifiRequired(false)
            queueSet.setAutoRetryTimes(1) // 所有任务在下载失败的时候都自动重试一次
            return queueSet
        }

    fun startDownload(
        list: List<DownloadResBean>,
        serial: Boolean,
        listener: FileDownloadListener
    ) {
        val queueSet = getQueueSet(listener)
        val tasks: MutableList<BaseDownloadTask> = ArrayList()
        for (temp in list) {
            val task = FileDownloader.getImpl().create(temp.url)
            task.path = temp.path
            tasks.add(task)
        }
        totalCounts += tasks.size
        AwLog.d(TAG, "startDownload totalCounts: " + totalCounts)
        if (serial) {
            // 串行执行该任务队列
            queueSet.downloadSequentially(tasks)
            // 如果你的任务不是一个List，可以考虑使用下面的方式，可读性更强
            //      queueSet.downloadSequentially(
            //              FileDownloader.getImpl().create(url).setPath(...),
            //              FileDownloader.getImpl().create(url).addHeader(...,...),
            //              FileDownloader.getImpl().create(url).setPath(...)
            //      );
        } else {
            // 并行执行该任务队列
            queueSet.downloadTogether(tasks)
            // 如果你的任务不是一个List，可以考虑使用下面的方式，可读性更强
            //    queueSet.downloadTogether(
            //            FileDownloader.getImpl().create(url).setPath(...),
            //            FileDownloader.getImpl().create(url).setPath(...),
            //            FileDownloader.getImpl().create(url).setSyncCallback(true)
            //    );
        }
        queueSet.start() // 最后你需要主动调用start方法来启动该Queue
    }

    private fun getQueueSet(listener: FileDownloadListener): FileDownloadQueueSet {
        val queueSet = FileDownloadQueueSet(listener)
        //        queueSet.disableCallbackProgressTimes();// 由于是队列任务, 这里是我们假设了现在不需要每个任务都回调`FileDownloadListener#progress`, 我们只关系每个任务是否完成, 所以这里这样设置可以很有效的减少ipc.
        queueSet.setCallbackProgressMinInterval(10000)
        queueSet.setWifiRequired(false)
        queueSet.setAutoRetryTimes(1) // 所有任务在下载失败的时候都自动重试一次
        return queueSet
    }

    private val queueTarget: FileDownloadListener = object : FileDownloadListener() {
        override fun pending(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
            AwLog.d(TAG, String.format("[pending] tag[%s] %d/%d", task.tag, soFarBytes, totalBytes))
        }

        override fun connected(
            task: BaseDownloadTask,
            etag: String,
            isContinue: Boolean,
            soFarBytes: Int,
            totalBytes: Int
        ) {
            AwLog.d(
                TAG,
                String.format(
                    "[connected] tag[%s] %s %B %d/%d",
                    task.tag,
                    etag,
                    isContinue,
                    soFarBytes,
                    totalBytes
                )
            )
        }

        override fun progress(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
            AwLog.d(
                TAG,
                String.format(
                    "下载中[progress] tag[%s] %d/%d , 下载速度: %d",
                    task.tag,
                    soFarBytes,
                    totalBytes,
                    task.speed
                )
            )
        }

        override fun blockComplete(task: BaseDownloadTask) {
            AwLog.d(TAG, String.format("[blockComplete] tag[%s]", task.tag))
        }

        override fun retry(
            task: BaseDownloadTask,
            ex: Throwable,
            retryingTimes: Int,
            soFarBytes: Int
        ) {
            AwLog.d(
                TAG, String.format(
                    "[retry] tag[%s] %s %d %d",
                    task.tag, ex, retryingTimes, soFarBytes
                )
            )
        }

        override fun completed(task: BaseDownloadTask) {
            finalCounts++
            AwLog.d(
                TAG, String.format(
                    "[completed] id[%d] oldFile[%B]",
                    task.id,
                    task.isReusedOldFile
                )
            )
            AwLog.d(
                TAG,
                String.format(
                    "---------------------------------- %s",
                    task.tag
                ) + " ," + String.format("%d/%d", finalCounts, totalCounts)
            )
            AwLog.d(
                TAG, String.format(
                    "下载完成id:%d, DownloadId: %d, TAG: %s, 总下载量: %d/%d, 文件名:  %s, 路径path:  %s, 路径targetFilePath:  %s, 下载url: %s, 平均速度: %d",
                    task.id,
                    task.downloadId,
                    task.tag,
                    finalCounts,
                    totalCounts,
                    task.filename,
                    task.path,
                    task.targetFilePath,
                    task.url,
                    task.speed
                )
            )
        }

        override fun paused(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
            finalCounts++
            AwLog.d(TAG, String.format("[paused] id[%d] %d/%d", task.id, soFarBytes, totalBytes))
            AwLog.d(
                TAG,
                String.format("############################## %s", task.tag) + " ," + String.format(
                    "%d/%d",
                    finalCounts,
                    totalCounts
                )
            )
        }

        override fun error(task: BaseDownloadTask, e: Throwable) {
            finalCounts++
            AwLog.d(TAG, e.message + " ," + String.format("%d/%d", finalCounts, totalCounts))
            AwLog.d(
                TAG, String.format(
                    "下载完成出错id:%d, DownloadId: %d, TAG: %s, 总下载量: %d/%d, 文件名:  %s, 路径path:  %s, 路径targetFilePath:  %s, 下载url: %s",
                    task.id,
                    task.downloadId,
                    task.tag,
                    finalCounts,
                    totalCounts,
                    task.filename,
                    task.path,
                    task.targetFilePath,
                    task.url
                )
            )
        }

        override fun warn(task: BaseDownloadTask) {
            finalCounts++
            AwLog.d(TAG, String.format("[warn] id[%d]", task.id))
            AwLog.d(
                TAG,
                String.format("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ %s", task.tag) + " ," + String.format(
                    "%d/%d",
                    finalCounts,
                    totalCounts
                )
            )
        }
    }
}